/**
 * @author: Gene
 * @age: 永远18岁的美少年
 * @Email： yangjianyun@58.com
 * @date: 2021-11-30 21:19:20
 * @description: Compilation 类,
 */
const path = require('path')
const fs = require("fs")
const baseDir = toUnixPath(process.cwd());
function toUnixPath(filePath) {
    return filePath.replace(/\\/g, '/');
}

class Compilation {
    constructor(options) {
        this.options = options
        // 当前编译用到的哪些对象入口
        this.fileDependices = []
    }

    build(onCompiled) {
        // 5. 根据配置中的`entry`找出入口文件
        let entry = {}
        // 兼容 entry 的值, 是对象和字符串的形状
        if (typeof this.options.entry === "string") {
            entry.main = this.options.entry
        } else {
            entry = this.options.entry
        }
        for (let entryName in entry) {
            // 获取到了所有的入口文件的绝对路径,  把所有的路径中的反斜杠 \ 替换为 /
            let entryPath = path.posix.join(baseDir, entry[entryName])
            console.log(entryPath, 333);
            this.fileDependices.push(entryPath)
            //    6. 从入口文件出发,调用所有配置的`Loader`对模块进行编译
            let entryModule = this.buildModule(entryName, entryPath)
            console.log(entryModule);
        }
        onCompiled(null, {}, this.fileDependices)
    }

    /**
     * @param name 编译模块
     * @param modulePath 模块的路径
     */
    buildModule(name, modulePath) {
        // 61. 读取源代码的内容
        let sourceCode = fs.readFileSync(modulePath, "utf8")
        // 6.2匹配此模块需要使用的 loader
        let {rules} = this.options.module
        let loaders = []
        rules.forEach((rule) => {
            // 如果正则匹配上了, 则把 此 rule 对应的 loader 添加到 loaders 的数组里去.
            if (modulePath.match(rule.test)) {
                loaders.push(...rule.use)
            }
        })
        // 从右往左执行 loader 
        sourceCode = loaders.reduceRight((sourceCode, loader) => {
            console.log(loader, 123123123);
            return require(loader)(sourceCode)
        }, sourceCode)
        console.log("sourceCode -->>", name, sourceCode);
    }
}

module.exports = Compilation